home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 440_01 / !best002.c < prev    next >
C/C++ Source or Header  |  1994-04-15  |  19KB  |  732 lines

  1. /*==========================================================================
  2.  *
  3.  *  !BEST002.C                                       Tuesday, April 12, 1994
  4.  *
  5.  *  source file 2D and 3D matrix/vector library
  6.  *  supplementary source file 2 for The BESTLibrary
  7.  *
  8.  *  Authored by George Vanous with reference to the 2D and 3D vector library
  9.  *  by Andrew Glassner from "Graphics Gems", Academic Press, 1990
  10.  *
  11.  *==========================================================================*/
  12.  
  13.  
  14. /* ------------------------------------------------------------------------ */
  15. /* ----------------------------  INCLUDE FILES  --------------------------- */
  16.  
  17. #include <math.h>
  18. #include "!best002.h"                  /* include !BEST002.H in compilation */
  19.  
  20. /*==========================================================================
  21.  *                               3X3 MATRICES
  22.  *--------------------------------------------------------------------------*/
  23.  
  24. /*----------------------------------------------------------------------------
  25.  * C = A + B
  26.  * RETURNS: C
  27.  */
  28. matrix3 *m3_add(matrix3 *A, matrix3 *B, matrix3 *C)
  29. {
  30.   word i;
  31.   register word j;
  32.  
  33.   for (i = 0; i < 3; i++) {
  34.     for (j = 0; j < 3; j++)
  35.       C->element[i][j] = A->element[i][j] + B->element[i][j];
  36.   }
  37.   return( C );
  38. }
  39.  
  40. /*----------------------------------------------------------------------------
  41.  * RETURNS: copy of A
  42.  */
  43. matrix3 *m3_copy(matrix3 *A)
  44. {
  45.   matrix3 *B = NEWTYPE(matrix3);
  46.   register word i, j;
  47.  
  48.   for (i = 0; i < 3; i++) {
  49.     for (j = 0; j < 3; j++)
  50.       B->element[i][j] = A->element[i][j];
  51.   }
  52.   return( B );
  53. }
  54.  
  55. /*----------------------------------------------------------------------------
  56.  * C = A * B
  57.  * RETURNS: C
  58.  */
  59. matrix3 *m3_mul(matrix3 *A, matrix3 *B, matrix3 *C)
  60. {
  61.   word i;
  62.   register word j, k;
  63.  
  64.   for (i = 0; i < 3; i++) {
  65.     for (j = 0; j < 3; j++) {
  66.       C->element[i][j] = 0;
  67.       for (k = 0; k < 3; k++)
  68.         C->element[i][j] += A->element[i][k] * B->element[k][j];
  69.     }
  70.   }
  71.   return( C );
  72. }
  73.  
  74. /*----------------------------------------------------------------------------
  75.  * RETURNS: new 3x3 matrix initialized to a[3][3]
  76.  */
  77. matrix3 *m3_new(double *a[3][3])
  78. {
  79.   matrix3 *A = NEWTYPE(matrix3);
  80.   register word i, j;
  81.  
  82.   for (i = 0; i < 3; i++) {
  83.     for (j = 0; j < 3; j++)
  84.       A->element[i][j] = *a[i][j];
  85.   }
  86.   return( A );
  87. }
  88. /*----------------------------------------------------------------------------
  89.  * C = A - B
  90.  * RETURNS: C
  91.  */
  92. matrix3 *m3_sub(matrix3 *A, matrix3 *B, matrix3 *C)
  93. {
  94.   word i;
  95.   register word j;
  96.  
  97.   for (i = 0; i < 3; i++) {
  98.     for (j = 0; j < 3; j++)
  99.       C->element[i][j] = A->element[i][j] - B->element[i][j];
  100.   }
  101.   return( C );
  102. }
  103.  
  104. /*----------------------------------------------------------------------------
  105.  * B = transpose(A)
  106.  * RETURNS: B
  107.  */
  108. matrix3 *m3_transpose(matrix3 *A, matrix3 *B)
  109. {
  110.   register word i, j;
  111.  
  112.   for (i = 0; i < 3; i++) {
  113.     for (j = 0; j < 3; j++)
  114.       B->element[i][j] = A->element[j][i];
  115.   }
  116.   return( B );
  117. }
  118.  
  119. /*==========================================================================
  120.  *                               4x4 MATRICES
  121.  *--------------------------------------------------------------------------*/
  122.  
  123. /*----------------------------------------------------------------------------
  124.  * C = A + B
  125.  * RETURNS: C
  126.  */
  127. matrix4 *m4_add(matrix4 *A, matrix4 *B, matrix4 *C)
  128. {
  129.   word i;
  130.   register word j;
  131.  
  132.   for (i = 0; i < 4; i++) {
  133.     for (j = 0; j < 4; j++)
  134.       C->element[i][j] = A->element[i][j] + B->element[i][j];
  135.   }
  136.   return( C );
  137. }
  138.  
  139. /*----------------------------------------------------------------------------
  140.  * RETURNS: copy of A
  141.  */
  142. matrix4 *m4_copy(matrix4 *A)
  143. {
  144.   matrix4 *B = NEWTYPE(matrix4);
  145.   register word i, j;
  146.  
  147.   for (i = 0; i < 4; i++) {
  148.     for (j = 0; j < 4; j++)
  149.       B->element[i][j] = A->element[i][j];
  150.   }
  151.   return( B );
  152. }
  153.  
  154. /*----------------------------------------------------------------------------
  155.  * C = A * B
  156.  * RETURNS: C
  157.  */
  158. matrix4 *m4_mul(matrix4 *A, matrix4 *B, matrix4 *C)
  159. {
  160.   word i;
  161.   register word j, k;
  162.  
  163.   for (i = 0; i < 4; i++) {
  164.     for (j = 0; j < 4; j++) {
  165.       c->element[i][j] = 0;
  166.       for (k = 0; k < 4; k++)
  167.         C->element[i][j] += A->element[i][k] * B->element[k][j];
  168.     }
  169.   }
  170.   return( C );
  171. }
  172.  
  173. /*----------------------------------------------------------------------------
  174.  * RETURNS: new 4x4 matrix initialized to a[4][4]
  175.  */
  176. matrix4 *m4_new(double *a[4][4])
  177. {
  178.   matrix4 *A = NEWTYPE(matrix4);
  179.   register word i, j;
  180.  
  181.   for (i = 0; i < 4; i++) {
  182.     for (j = 0; j < 4; j++)
  183.       A->element[i][j] = *a[i][j];
  184.   }
  185.   return( A );
  186. }
  187.  
  188. /*----------------------------------------------------------------------------
  189.  * C = A - B
  190.  * RETURNS: C
  191.  */
  192. matrix4 *m4_sub(matrix4 *A, matrix4 *B, matrix4 *C)
  193. {
  194.   word i;
  195.   register word j;
  196.  
  197.   for (i = 0; i < 4; i++) {
  198.     for (j = 0; j < 4; j++)
  199.       C->element[i][j] = A->element[i][j] - B->element[i][j];
  200.   }
  201.   return( C );
  202. }
  203.  
  204. /*----------------------------------------------------------------------------
  205.  * B = transpose(A)
  206.  * RETURNS: B
  207.  */
  208. matrix4 *m4_transpose(matrix4 *A, matrix4 *B)
  209. {
  210.   register word i, j;
  211.  
  212.   for (i = 0; i < 4; i++) {
  213.     for (j = 0; j < 4; j++)
  214.       B->element[i][j] = A->element[j][i];
  215.   }
  216.   return( B );
  217. }
  218.  
  219. /*==========================================================================
  220.  *                                2D VECTORS
  221.  *--------------------------------------------------------------------------*/
  222.  
  223. /*----------------------------------------------------------------------------
  224.  * w = u + v
  225.  * RETURNS: w
  226.  */
  227. vector2 *v2_add(vector2 *u, vector2 *v, vector2 *w)
  228. {
  229.   w->x = u->x + v->x, w->y = u->y + v->y;
  230.   return( w );
  231. }
  232.         
  233. /*----------------------------------------------------------------------------
  234.  * w = c1(u) + c2(v)
  235.  * RETURNS: w
  236.  */
  237. vector2 *v2_combine(vector2 *u, double c1,
  238.                     vector2 *v, double c2, vector2 *w)
  239. {
  240.   w->x = (c1 * u->x) + (c2 * v->x);
  241.   w->y = (c1 * u->y) + (c2 * v->y);
  242.   return( w );
  243. }
  244.  
  245. /*----------------------------------------------------------------------------
  246.  * RETURNS: copy of u
  247.  */
  248. vector2 *v2_copy(vector2 *v)
  249. {
  250.   vector2 *w = NEWTYPE(vector2);
  251.  
  252.   w->x = v->x, w->y = v->y;
  253.   return( w );
  254. }
  255.         
  256. /*----------------------------------------------------------------------------
  257.  * w = u dot v
  258.  * RETURNS: w
  259.  */
  260. double v2_dot(vector2 *u, vector2 *v)
  261. {
  262.   return( (u->x * v->x) + (u->y * v->y) );
  263. }
  264.  
  265. /*----------------------------------------------------------------------------
  266.  * RETURNS: magnitude of v
  267.  */
  268. double v2_len(vector2 *v)
  269. {
  270.   return( sqrt(V2SquaredLength(v)) );
  271. }
  272.         
  273. /*----------------------------------------------------------------------------
  274.  * RETURNS: magnitude of v squared
  275.  */
  276. double v2_len_sqr(vector2 *v)
  277. {
  278.   return( (v->x * v->x) + (v->y * v->y) );
  279. }
  280.  
  281. /*----------------------------------------------------------------------------
  282.  * w = linear interpolation between lo and hi by amount alpha
  283.  * RETURNS: w
  284.  */
  285. vector2 *v2_lerp(vector2 *lo, vector2 *hi, double alpha, vector2 *w)
  286. {
  287.   w->x = LERP(alpha, lo->x, hi->x);
  288.   w->y = LERP(alpha, lo->y, hi->y);
  289.   return( w );
  290. }
  291.  
  292. /*----------------------------------------------------------------------------
  293.  * w = u * v (multiplication component-wise)
  294.  * RETURNS: w
  295.  */
  296. vector2 *v2_mul(vector2 *u, vector2 *v, vector2 *w)
  297. {
  298.   w->x = u->x * v->x;
  299.   w->y = u->y * v->y;
  300.   return( w );
  301. }
  302.  
  303. /*----------------------------------------------------------------------------
  304.  * RETURNS: transformed point p * projection matrix m
  305.  */
  306. point2 *v2_mul_by_proj(point2 *p, matrix3 *A)
  307. {
  308.   double w;
  309.   point2 q;
  310.  
  311.   q.x = (p->x * A->element[0][0]) +
  312.         (p->y * A->element[1][0]) + A->element[2][0];
  313.   q.y = (p->x * A->element[0][1]) +
  314.         (p->y * A->element[1][1]) + A->element[2][1];
  315.   w = (p->x * A->element[0][2]) +
  316.       (p->y * A->element[1][2]) + A->element[2][2];
  317.   if (w != 0.0)
  318.     q.x /= w, q.y /= w;
  319.   *p = q;
  320.   re